home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / cp2dekit / samples / xmplay.cpp < prev    next >
C/C++ Source or Header  |  1996-12-29  |  47KB  |  1,882 lines

  1. //***************************************************************************
  2. //
  3. // this file is (c) '94-'96 Niklas Beisert
  4. //
  5. // this file is part of the cubic player development kit.
  6. // you may only use/modify/spread this file under the terms stated
  7. // in the cubic player development kit accompanying documentation.
  8. //
  9. //***************************************************************************
  10.  
  11. //[filetype 0]
  12. //  color=1
  13. //  name=MOD
  14. //  interface=_plCubicPlayer
  15. //  pllink=playxm
  16. //  player=_xmpPlayer
  17. //[filetype 10]
  18. //  color=3
  19. //  name=XM
  20. //  interface=_plCubicPlayer
  21. //  pllink=playxm
  22. //  player=_xmpPlayer
  23.  
  24.  
  25. // wavetable device example
  26.  
  27. // future enhancements
  28. // channel mapper
  29.  
  30. #include <string.h>
  31. #include "mcp.h"
  32. #include "binfile.h"
  33. #include "gmdinst.h"
  34. #include "xmplay.h"
  35. #include "err.h"
  36.  
  37. struct channel
  38. {
  39.   int chVol;
  40.   int chFinalVol;
  41.   int chPan;
  42.   int chFinalPan;
  43.   long chPitch;
  44.   long chFinalPitch;
  45.  
  46.   unsigned char chCurIns;
  47.   int chCurNormNote;
  48.   unsigned char chSustain;
  49.   unsigned short chFadeVol;
  50.   unsigned short chAVibPos;
  51.   unsigned long chAVibSwpPos;
  52.   unsigned long chVolEnvPos;
  53.   unsigned long chPanEnvPos;
  54.  
  55.   unsigned char chDefVol;
  56.   int chDefPan;
  57.   unsigned char chCommand;
  58.   unsigned char chVCommand;
  59.   long chPortaToPitch;
  60.   long chPortaToVal;
  61.   unsigned char chVolSlideVal;
  62.   unsigned char chGVolSlideVal;
  63.   unsigned char chVVolPanSlideVal;
  64.   unsigned char chPanSlideVal;
  65.   unsigned char chFineVolSlideUVal;
  66.   unsigned char chFineVolSlideDVal;
  67.   long chPortaUVal;
  68.   long chPortaDVal;
  69.   unsigned char chFinePortaUVal;
  70.   unsigned char chFinePortaDVal;
  71.   unsigned char chXFinePortaUVal;
  72.   unsigned char chXFinePortaDVal;
  73.   unsigned char chVibRate;
  74.   unsigned char chVibPos;
  75.   unsigned char chVibType;
  76.   unsigned char chVibDep;
  77.   unsigned char chTremRate;
  78.   unsigned char chTremPos;
  79.   unsigned char chTremType;
  80.   unsigned char chTremDep;
  81.   unsigned char chPatLoopCount;
  82.   unsigned char chPatLoopStart;
  83.   unsigned char chArpPos;
  84.   unsigned char chArpNotes[3];
  85.   unsigned char chActionTick;
  86.   unsigned char chMRetrigPos;
  87.   unsigned char chMRetrigLen;
  88.   unsigned char chMRetrigAct;
  89.   unsigned char chDelayNote;
  90.   unsigned char chOffset;
  91.   unsigned char chGlissando;
  92.   unsigned char chTremorPos;
  93.   unsigned char chTremorLen;
  94.   unsigned char chTremorOff;
  95.  
  96.   int nextstop;
  97.   int nextsamp;
  98.   int nextpos;
  99.   sample *cursamp;
  100. };
  101.  
  102. static int looping;
  103. static int looped;
  104. static int usersetpos;
  105. static channel channels[32];
  106.  
  107. static unsigned char mutech[32];
  108. static unsigned char globalvol;
  109.  
  110. static unsigned char curtick;
  111. static unsigned char curtempo;
  112. static unsigned char tick0;
  113.  
  114. static int currow;
  115. static unsigned char (*patptr)[5];
  116. static int patlen;
  117. static int curord;
  118.  
  119. static int nord;
  120. static int ninst;
  121. static int nsamp;
  122. static int linearfreq;
  123. static int nchan;
  124. static int loopord;
  125. static int nenv;
  126. static instrument *instruments;
  127. static sample *samples;
  128. static envelope *envelopes;
  129. static unsigned char (**patterns)[5];
  130. static unsigned short *orders;
  131. static unsigned short *patlens;
  132.  
  133. static int jumptoord;
  134. static int jumptorow;
  135. static int patdelay;
  136.  
  137. static unsigned char procnot;
  138. static unsigned char procins;
  139. static unsigned char procvol;
  140. static unsigned char proccmd;
  141. static unsigned char procdat;
  142. static unsigned char notedelayed;
  143. static int firstspeed;
  144.  
  145.  
  146. static short sintab[256]=
  147. {
  148.       0,    50,   100,   151,   201,   251,   301,   350,
  149.     400,   449,   498,   546,   595,   642,   690,   737,
  150.     784,   830,   876,   921,   965,  1009,  1053,  1096,
  151.    1138,  1179,  1220,  1260,  1299,  1338,  1375,  1412,
  152.    1448,  1483,  1517,  1551,  1583,  1615,  1645,  1674,
  153.    1703,  1730,  1757,  1782,  1806,  1829,  1851,  1872,
  154.    1892,  1911,  1928,  1945,  1960,  1974,  1987,  1998,
  155.    2009,  2018,  2026,  2033,  2038,  2042,  2046,  2047,
  156.    2048,  2047,  2046,  2042,  2038,  2033,  2026,  2018,
  157.    2009,  1998,  1987,  1974,  1960,  1945,  1928,  1911,
  158.    1892,  1872,  1851,  1829,  1806,  1782,  1757,  1730,
  159.    1703,  1674,  1645,  1615,  1583,  1551,  1517,  1483,
  160.    1448,  1412,  1375,  1338,  1299,  1260,  1220,  1179,
  161.    1138,  1096,  1053,  1009,   965,   921,   876,   830,
  162.     784,   737,   690,   642,   595,   546,   498,   449,
  163.     400,   350,   301,   251,   201,   151,   100,    50,
  164.       0,   -50,  -100,  -151,  -201,  -251,  -301,  -350,
  165.    -400,  -449,  -498,  -546,  -595,  -642,  -690,  -737,
  166.    -784,  -830,  -876,  -921,  -965, -1009, -1053, -1096,
  167.   -1138, -1179, -1220, -1260, -1299, -1338, -1375, -1412,
  168.   -1448, -1483, -1517, -1551, -1583, -1615, -1645, -1674,
  169.   -1703, -1730, -1757, -1782, -1806, -1829, -1851, -1872,
  170.   -1892, -1911, -1928, -1945, -1960, -1974, -1987, -1998,
  171.   -2009, -2018, -2026, -2033, -2038, -2042, -2046, -2047,
  172.   -2048, -2047, -2046, -2042, -2038, -2033, -2026, -2018,
  173.   -2009, -1998, -1987, -1974, -1960, -1945, -1928, -1911,
  174.   -1892, -1872, -1851, -1829, -1806, -1782, -1757, -1730,
  175.   -1703, -1674, -1645, -1615, -1583, -1551, -1517, -1483,
  176.   -1448, -1412, -1375, -1338, -1299, -1260, -1220, -1179,
  177.   -1138, -1096, -1053, -1009,  -965,  -921,  -876,  -830,
  178.    -784,  -737,  -690,  -642,  -595,  -546,  -498,  -449,
  179.    -400,  -350,  -301,  -251,  -201,  -151,  -100,   -50
  180. };
  181.  
  182. static int freqrange(int x)
  183. {
  184.   if (linearfreq)
  185.     return (x<-72*256)?-72*256:(x>96*256)?96*256:x;
  186.   else
  187.     return (x<107)?107:(x>438272)?438272:x;
  188. }
  189.  
  190. static int volrange(int x)
  191. {
  192.   return (x<0)?0:(x>0x40)?0x40:x;
  193. }
  194.  
  195. static int panrange(int x)
  196. {
  197.   return (x<0)?0:(x>0xFF)?0xFF:x;
  198. }
  199.  
  200.  
  201. static void PlayNote(channel &ch)
  202. {
  203.   int portatmp=0;
  204.  
  205.   if (procins>ninst)
  206.     procins=0;
  207.  
  208.   if (proccmd==3)
  209.     portatmp=1;
  210.   if (proccmd==5)
  211.     portatmp=1;
  212.   if (procvol>=0xF0)
  213.     portatmp=1;
  214.  
  215.   int keyoff=0;
  216.   if (procnot==97)
  217.   {
  218.     procnot=0;
  219.     keyoff=1;
  220.   }
  221.   if ((proccmd==20)&&!procdat)
  222.     keyoff=1;
  223.  
  224.   if (procins&&(procins<=ninst))
  225.     ch.chCurIns=procins;
  226.  
  227.   if (!ch.chCurIns)
  228.     return;
  229.  
  230.   if (procnot)
  231.   {
  232.     if (procins!=0)
  233.       ch.chSustain=1;
  234.  
  235.     ch.chDelayNote=procnot;
  236.     if (proccmd==49)
  237.     {
  238.       if (procdat!=0)
  239.         return;
  240.     }
  241.  
  242.     procnot--;
  243.     if (!portatmp)
  244.     {
  245.       ch.nextstop=1;
  246.  
  247.       instrument &ins=instruments[ch.chCurIns-1];
  248.       if (instruments[ch.chCurIns-1].samples[procnot]>nsamp)
  249.         return;
  250.       ch.cursamp=&samples[instruments[ch.chCurIns-1].samples[procnot]];
  251.  
  252.       ch.nextsamp=ch.cursamp->handle;
  253.  
  254.       if (procins)
  255.       {
  256.         ch.chDefVol=(ch.cursamp->stdvol+1)>>2;
  257.         ch.chDefPan=ch.cursamp->stdpan;
  258.       }
  259.  
  260.       ch.chCurNormNote=ch.cursamp->normnote;
  261.  
  262.       int frq=48*256-((procnot<<8)-ch.chCurNormNote);
  263.       if (!linearfreq)
  264.         frq=mcpGetFreq6848(frq);
  265.       ch.chPitch=frq;
  266.       ch.chFinalPitch=frq;
  267.       ch.chPortaToPitch=frq;
  268.  
  269.       ch.nextpos=0;
  270.  
  271.       if (proccmd==9)
  272.       {
  273.         if (procdat!=0)
  274.           ch.chOffset=procdat;
  275.         ch.nextpos=ch.chOffset<<8;
  276.       }
  277.  
  278.       ch.chVibPos=0;
  279.       ch.chTremPos=0;
  280.       ch.chArpPos=0;
  281.       ch.chMRetrigPos=0;
  282.       ch.chTremorPos=0;
  283.     }
  284.     else
  285.     {
  286.       int frq=48*256-((procnot<<8)-ch.chCurNormNote);
  287.       if (!linearfreq)
  288.         frq=mcpGetFreq6848(frq);
  289.       ch.chPortaToPitch=frq;
  290.     }
  291.   }
  292.  
  293.   if (keyoff&&ch.cursamp)
  294.   {
  295.     ch.chSustain=0;
  296.     if ((ch.cursamp->volenv>=nenv)&&!procins)
  297.       ch.chFadeVol=0;
  298.   }
  299.  
  300.   if (!ch.chSustain)
  301.     return;
  302.   if (!procins)
  303.     return;
  304.  
  305.   if (!notedelayed)
  306.   {
  307.     ch.chVol=ch.chDefVol;
  308.     ch.chFinalVol=ch.chDefVol;
  309.     if (ch.chDefPan!=-1)
  310.     {
  311.       ch.chPan=ch.chDefPan;
  312.       ch.chFinalPan=ch.chDefPan;
  313.     }
  314.   }
  315.   ch.chFadeVol=0x8000;
  316.   ch.chAVibPos=0;
  317.   ch.chAVibSwpPos=0;
  318.   ch.chVolEnvPos=0;
  319.   ch.chPanEnvPos=0;
  320. }
  321.  
  322. static unsigned short notetab[16]={32768,30929,29193,27554,26008,24548,23170,21870,20643,19484,18390,17358,16384,15464,14596,13777};
  323.  
  324. static void xmpPlayTick()
  325. {
  326.   if (firstspeed)
  327.   {
  328.     mcpSet(-1, mcpGSpeed, firstspeed);
  329.     firstspeed=0;
  330.   }
  331.  
  332.   tick0=0;
  333.   int i;
  334.   for (i=0; i<nchan; i++)
  335.   {
  336.     channel &ch=channels[i];
  337.     ch.chFinalVol=ch.chVol;
  338.     ch.chFinalPan=ch.chPan;
  339.     ch.chFinalPitch=ch.chPitch;
  340.     ch.nextstop=0;
  341.     ch.nextsamp=-1;
  342.     ch.nextpos=-1;
  343.   }
  344.  
  345.   curtick++;
  346.   if (curtick>=curtempo)
  347.     curtick=0;
  348.  
  349.   if (!curtick&&patdelay)
  350.   {
  351.     if (jumptoord!=-1)
  352.     {
  353.       if (jumptoord!=curord)
  354.         for (i=0; i<nchan; i++)
  355.         {
  356.           channel &ch=channels[i];
  357.           ch.chPatLoopCount=0;
  358.           ch.chPatLoopStart=0;
  359.         }
  360.  
  361.       if (jumptoord>=nord)
  362.         jumptoord=loopord;
  363.       if ((jumptoord<curord)&&!usersetpos)
  364.         looped=1;
  365.       usersetpos=0;
  366.  
  367.       curord=jumptoord;
  368.       currow=jumptorow;
  369.       jumptoord=-1;
  370.       patlen=patlens[orders[curord]];
  371.       patptr=patterns[orders[curord]];
  372.     }
  373.   }
  374.  
  375.   if (!curtick&&patdelay)
  376.   {
  377.     patdelay--;
  378.   }
  379.   else
  380.   if (!curtick)
  381.   {
  382.     tick0=1;
  383.  
  384.     currow++;
  385.     if ((jumptoord==-1)&&(currow>=patlen))
  386.     {
  387.       jumptoord=curord+1;
  388.       jumptorow=0;
  389.     }
  390.     if (jumptoord!=-1)
  391.     {
  392.       if (jumptoord!=curord)
  393.         for (i=0; i<nchan; i++)
  394.         {
  395.           channel &ch=channels[i];
  396.           ch.chPatLoopCount=0;
  397.           ch.chPatLoopStart=0;
  398.         }
  399.  
  400.       if (jumptoord>=nord)
  401.         jumptoord=loopord;
  402.       if ((jumptoord<curord)&&!usersetpos)
  403.         looped=1;
  404.       usersetpos=0;
  405.  
  406.       curord=jumptoord;
  407.       currow=jumptorow;
  408.       jumptoord=-1;
  409.       patlen=patlens[orders[curord]];
  410.       patptr=patterns[orders[curord]];
  411.     }
  412.  
  413.  
  414.     for (i=0; i<nchan; i++)
  415.     {
  416.       channel &ch=channels[i];
  417.       procnot=patptr[nchan*currow+i][0];
  418.       procins=patptr[nchan*currow+i][1];
  419.       procvol=patptr[nchan*currow+i][2];
  420.       proccmd=patptr[nchan*currow+i][3];
  421.       procdat=patptr[nchan*currow+i][4];
  422.  
  423.       notedelayed=0;
  424.       PlayNote(ch);
  425.  
  426.       ch.chVCommand=procvol>>4;
  427.       procvol&=0xF;
  428.       switch (ch.chVCommand)
  429.       {
  430.       case 1: case 2: case 3: case 4:
  431.         ch.chFinalVol=ch.chVol=procvol+ch.chVCommand*0x10-0x10;
  432.         break;
  433.       case 5:
  434.         ch.chFinalVol=ch.chVol=0x40;
  435.         break;
  436.       case 6: case 7: case 13: case 14:
  437.         ch.chVVolPanSlideVal=procvol;
  438.         break;
  439.       case 8:
  440.         ch.chVol-=procvol;
  441.         ch.chFinalVol=ch.chVol=volrange(ch.chVol);
  442.         break;
  443.       case 9:
  444.         ch.chVol+=procvol;
  445.         ch.chFinalVol=ch.chVol=volrange(ch.chVol);
  446.         break;
  447.       case 10:
  448.         if (procvol)
  449.           ch.chVibRate=(procvol<<2);
  450.         break;
  451.       case 11:
  452.         if (procvol)
  453.           ch.chVibDep=(procvol<<2);
  454.         break;
  455.       case 12:
  456.         ch.chFinalPan=ch.chPan=procvol*0x11;
  457.         break;
  458.       case 15:
  459.         if (procvol)
  460.           ch.chPortaToVal=procvol<<8;
  461.         break;
  462.       }
  463.  
  464.       ch.chCommand=proccmd;
  465.       switch (ch.chCommand)
  466.       {
  467.       case 0:
  468.         if (procdat)
  469.           ch.chCommand=0xFF;
  470.         ch.chArpNotes[0]=0;
  471.         ch.chArpNotes[1]=procdat>>4;
  472.         ch.chArpNotes[2]=procdat&0xF;
  473.         break;
  474.       case 1:
  475.         if (procdat)
  476.           ch.chPortaUVal=procdat<<4;
  477.         break;
  478.       case 2:
  479.         if (procdat)
  480.           ch.chPortaDVal=procdat<<4;
  481.         break;
  482.       case 3:
  483.         if (procdat)
  484.           ch.chPortaToVal=procdat<<4;
  485.         break;
  486.       case 4:
  487.         if (procdat&0xF)
  488.           ch.chVibDep=(procdat&0xF)<<2;
  489.         if (procdat&0xF0)
  490.           ch.chVibRate=(procdat>>4)<<2;
  491.         break;
  492.       case 5: case 6: case 10:
  493.         if (procdat)
  494.           ch.chVolSlideVal=procdat;
  495.         break;
  496.       case 7:
  497.         if (procdat&0xF)
  498.           ch.chTremDep=(procdat&0xF)<<2;
  499.         if (procdat&0xF0)
  500.           ch.chTremRate=(procdat>>4)<<2;
  501.         break;
  502.       case 8:
  503.         ch.chFinalPan=ch.chPan=procdat;
  504.         break;
  505.       case 11:
  506.         jumptoord=procdat;
  507.         jumptorow=0;
  508.         break;
  509.       case 12:
  510.         ch.chFinalVol=ch.chVol=volrange(procdat);
  511.         break;
  512.       case 13:
  513.         if (jumptoord==-1)
  514.           jumptoord=curord+1;
  515.         jumptorow=(procdat&0xF)+(procdat>>4)*10;
  516.         break;
  517.       case 15:
  518.         if (!procdat)
  519.         {
  520.           jumptoord=procdat;
  521.           jumptorow=0;
  522.           break;
  523.         }
  524.         if (procdat>=0x20)
  525.           mcpSet(-1, mcpGSpeed, 256*2*procdat/5);
  526.         else
  527.           curtempo=procdat;
  528.         break;
  529.       case 16:
  530.         globalvol=volrange(procdat);
  531.         break;
  532.       case 17:
  533.         if (procdat)
  534.           ch.chGVolSlideVal=procdat;
  535.         break;
  536.       case 20: case 45: case 48: case 49:
  537.         ch.chActionTick=procdat;
  538.         break;
  539.       case 21:
  540.         ch.chVolEnvPos=ch.chPanEnvPos=procdat;
  541.         if (ch.cursamp->volenv<nenv)
  542.           if (ch.chVolEnvPos>envelopes[ch.cursamp->volenv].len)
  543.             ch.chVolEnvPos=envelopes[ch.cursamp->volenv].len;
  544.         if (ch.cursamp->panenv<nenv)
  545.           if (ch.chPanEnvPos>envelopes[ch.cursamp->panenv].len)
  546.             ch.chPanEnvPos=envelopes[ch.cursamp->panenv].len;
  547.         break;
  548.       case 25:
  549.         if (procdat)
  550.           ch.chPanSlideVal=procdat;
  551.         break;
  552.       case 27:
  553.         if (procdat)
  554.         {
  555.           ch.chMRetrigLen=procdat&0xF;
  556.           ch.chMRetrigAct=procdat>>4;
  557.           ch.chMRetrigPos=0;
  558.         }
  559.         break;
  560.       case 29:
  561.         if (procdat)
  562.         {
  563.           ch.chTremorLen=(procdat&0xF)+(procdat>>4)+2;
  564.           ch.chTremorOff=(procdat>>4)+1;
  565.           ch.chTremorPos=0;
  566.         }
  567.         break;
  568.       case 33:
  569.         if ((procdat>>4)==1)
  570.         {
  571.           if (procdat&0xF)
  572.             ch.chXFinePortaUVal=procdat&0xF;
  573.           ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch-(ch.chXFinePortaUVal<<2));
  574.         }
  575.         else
  576.         if ((procdat>>4)==2)
  577.         {
  578.           if (procdat&0xF)
  579.             ch.chXFinePortaDVal=procdat&0xF;
  580.           ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch+(ch.chXFinePortaDVal<<2));
  581.         }
  582.         break;
  583.       case 37:
  584.         if (procdat)
  585.           ch.chFinePortaUVal=procdat;
  586.         ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch-(ch.chFinePortaUVal<<4));
  587.         break;
  588.       case 38:
  589.         if (procdat)
  590.           ch.chFinePortaDVal=procdat;
  591.         ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch-(ch.chFinePortaDVal<<4));
  592.         break;
  593.       case 39:
  594.         ch.chGlissando=procdat;
  595.         break;
  596.       case 40:
  597.         ch.chVibType=procdat&3;
  598.         break;
  599.       case 42:
  600.         if (procdat)
  601.           ch.chPatLoopStart=currow;
  602.         else
  603.         {
  604.           ch.chPatLoopCount++;
  605.           if (ch.chPatLoopCount<=procdat)
  606.           {
  607.             jumptorow=ch.chPatLoopStart;
  608.             jumptoord=curord;
  609.           }
  610.           else
  611.           {
  612.             ch.chPatLoopCount=0;
  613.             ch.chPatLoopStart=currow+1;
  614.           }
  615.         }
  616.         break;
  617.       case 43:
  618.         ch.chTremType=procdat&3;
  619.         break;
  620.       case 44:
  621.         ch.chFinalPan=ch.chPan=procdat*0x11;
  622.         break;
  623.       case 46:
  624.         if (procdat)
  625.           ch.chFineVolSlideUVal=procdat;
  626.         ch.chFinalVol=ch.chVol=volrange(ch.chVol+ch.chFineVolSlideUVal);
  627.         break;
  628.       case 47:
  629.         if (procdat)
  630.           ch.chFineVolSlideDVal=procdat;
  631.         ch.chFinalVol=ch.chVol=volrange(ch.chVol-ch.chFineVolSlideDVal);
  632.         break;
  633.       case 50:
  634.         patdelay=procdat;
  635.         break;
  636.       }
  637.     }
  638.   }
  639.  
  640.   for (i=0; i<nchan; i++)
  641.   {
  642.     channel &ch=channels[i];
  643.  
  644.     switch (ch.chVCommand)
  645.     {
  646.     case 6:
  647.       if (tick0)
  648.         break;
  649.       ch.chFinalVol=ch.chVol=volrange(ch.chVol-ch.chVVolPanSlideVal);
  650.       break;
  651.     case 7:
  652.       if (tick0)
  653.         break;
  654.       ch.chFinalVol=ch.chVol=volrange(ch.chVol+ch.chVVolPanSlideVal);
  655.       break;
  656.     case 11:
  657.       switch (ch.chVibType)
  658.       {
  659.       case 0:
  660.         ch.chFinalPitch=freqrange((( sintab[ch.chVibPos] *ch.chVibDep)>>8)+ch.chFinalPitch);
  661.         break;
  662.       case 1:
  663.         ch.chFinalPitch=freqrange((( (ch.chVibPos-0x80)   *ch.chVibDep)>>4)+ch.chFinalPitch);
  664.         break;
  665.       case 2:
  666.         ch.chFinalPitch=freqrange((( ((ch.chVibPos&0x80)-0x40) *ch.chVibDep)>>3)+ch.chFinalPitch);
  667.         break;
  668.       }
  669.       if (!tick0)
  670.         ch.chVibPos+=ch.chVibRate;
  671.       break;
  672.     case 13:
  673.       if (tick0)
  674.         break;
  675.       ch.chFinalPan=ch.chPan=panrange(ch.chPan-ch.chVVolPanSlideVal);
  676.       break;
  677.     case 14:
  678.       if (tick0)
  679.         break;
  680.       ch.chFinalPan=ch.chPan=panrange(ch.chPan+ch.chVVolPanSlideVal);
  681.       break;
  682.     case 15:
  683.       if (!tick0)
  684.         if (ch.chPitch<ch.chPortaToPitch)
  685.         {
  686.           ch.chPitch+=ch.chPortaToVal;
  687.           if (ch.chPitch>ch.chPortaToPitch)
  688.             ch.chPitch=ch.chPortaToPitch;
  689.         }
  690.         else
  691.         {
  692.           ch.chPitch-=ch.chPortaToVal;
  693.           if (ch.chPitch<ch.chPortaToPitch)
  694.             ch.chPitch=ch.chPortaToPitch;
  695.         }
  696.       if (ch.chGlissando)
  697.       {
  698.         if (linearfreq)
  699.           ch.chFinalPitch=((ch.chPitch+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote;
  700.         else
  701.           ch.chFinalPitch=mcpGetFreq6848(((mcpGetNote6848(ch.chPitch)+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote);
  702.       }
  703.       else
  704.         ch.chFinalPitch=ch.chPitch;
  705.       break;
  706.     }
  707.  
  708.     switch (ch.chCommand)
  709.     {
  710.     case 0:
  711.       if (linearfreq)
  712.         ch.chFinalPitch=freqrange(ch.chFinalPitch-(ch.chArpNotes[ch.chArpPos]<<8));
  713.       else
  714.         ch.chFinalPitch=freqrange((ch.chFinalPitch*notetab[ch.chArpNotes[ch.chArpPos]])>>15);
  715.       ch.chArpPos++;
  716.       if (ch.chArpPos==3)
  717.          ch.chArpPos=0;
  718.       break;
  719.     case 1:
  720.       if (tick0)
  721.         break;
  722.       ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch-ch.chPortaUVal);
  723.       break;
  724.     case 2:
  725.       if (tick0)
  726.         break;
  727.       ch.chFinalPitch=ch.chPitch=freqrange(ch.chPitch+ch.chPortaDVal);
  728.       break;
  729.     case 3:
  730.       if (!tick0)
  731.         if (ch.chPitch<ch.chPortaToPitch)
  732.         {
  733.           ch.chPitch+=ch.chPortaToVal;
  734.           if (ch.chPitch>ch.chPortaToPitch)
  735.             ch.chPitch=ch.chPortaToPitch;
  736.         }
  737.         else
  738.         {
  739.           ch.chPitch-=ch.chPortaToVal;
  740.           if (ch.chPitch<ch.chPortaToPitch)
  741.             ch.chPitch=ch.chPortaToPitch;
  742.         }
  743.       if (ch.chGlissando)
  744.       {
  745.         if (linearfreq)
  746.           ch.chFinalPitch=((ch.chPitch+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote;
  747.         else
  748.           ch.chFinalPitch=mcpGetFreq6848(((mcpGetNote6848(ch.chPitch)+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote);
  749.       }
  750.       else
  751.         ch.chFinalPitch=ch.chPitch;
  752.       break;
  753.     case 4:
  754.       switch (ch.chVibType)
  755.       {
  756.       case 0:
  757.         ch.chFinalPitch=freqrange((( sintab[ch.chVibPos] *ch.chVibDep)>>8)+ch.chFinalPitch);
  758.         break;
  759.       case 1:
  760.         ch.chFinalPitch=freqrange((( (ch.chVibPos-0x80)   *ch.chVibDep)>>4)+ch.chFinalPitch);
  761.         break;
  762.       case 2:
  763.         ch.chFinalPitch=freqrange((( ((ch.chVibPos&0x80)-0x40) *ch.chVibDep)>>3)+ch.chFinalPitch);
  764.         break;
  765.       }
  766.       if (!tick0)
  767.         ch.chVibPos+=ch.chVibRate;
  768.       break;
  769.     case 5:
  770.       if (!tick0)
  771.         if (ch.chPitch<ch.chPortaToPitch)
  772.         {
  773.           ch.chPitch+=ch.chPortaToVal;
  774.           if (ch.chPitch>ch.chPortaToPitch)
  775.             ch.chPitch=ch.chPortaToPitch;
  776.         }
  777.         else
  778.         {
  779.           ch.chPitch-=ch.chPortaToVal;
  780.           if (ch.chPitch<ch.chPortaToPitch)
  781.             ch.chPitch=ch.chPortaToPitch;
  782.         }
  783.       if (ch.chGlissando)
  784.       {
  785.         if (linearfreq)
  786.           ch.chFinalPitch=((ch.chPitch+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote;
  787.         else
  788.           ch.chFinalPitch=mcpGetFreq6848(((mcpGetNote6848(ch.chPitch)+ch.chCurNormNote+0x80)&~0xFF)-ch.chCurNormNote);
  789.       }
  790.       else
  791.         ch.chFinalPitch=ch.chPitch;
  792.  
  793.       if (tick0)
  794.         break;
  795.       ch.chFinalVol=ch.chVol=volrange(ch.chVol+((ch.chVolSlideVal&0xF0)?(ch.chVolSlideVal>>4):-(ch.chVolSlideVal&0xF)));
  796.       break;
  797.     case 6:
  798.       switch (ch.chVibType)
  799.       {
  800.       case 0:
  801.         ch.chFinalPitch=freqrange((( sintab[ch.chVibPos] *ch.chVibDep)>>8)+ch.chFinalPitch);
  802.         break;
  803.       case 1:
  804.         ch.chFinalPitch=freqrange((( (ch.chVibPos-0x80)   *ch.chVibDep)>>4)+ch.chFinalPitch);
  805.         break;
  806.       case 2:
  807.         ch.chFinalPitch=freqrange((( ((ch.chVibPos&0x80)-0x40) *ch.chVibDep)>>3)+ch.chFinalPitch);
  808.         break;
  809.       }
  810.       if (!tick0)
  811.         ch.chVibPos+=ch.chVibRate;
  812.  
  813.       if (tick0)
  814.         break;
  815.       ch.chFinalVol=ch.chVol=volrange(ch.chVol+((ch.chVolSlideVal&0xF0)?(ch.chVolSlideVal>>4):-(ch.chVolSlideVal&0xF)));
  816.       break;
  817.     case 7:
  818.       switch (ch.chTremType)
  819.       {
  820.       case 0:
  821.         ch.chFinalVol+=(( sintab[ch.chTremPos] *ch.chTremDep)>>11);
  822.         break;
  823.       case 1:
  824.         ch.chFinalVol+=(( (ch.chTremPos-0x80)   *ch.chTremDep)>>7);
  825.         break;
  826.       case 2:
  827.         ch.chFinalVol+=(( ((ch.chTremPos&0x80)-0x40) *ch.chTremDep)>>6);
  828.         break;
  829.       }
  830.       ch.chFinalVol=volrange(ch.chFinalVol);
  831.       if (!tick0)
  832.         ch.chTremPos+=ch.chTremRate;
  833.       break;
  834.     case 10:
  835.       if (tick0)
  836.         break;
  837.       ch.chFinalVol=ch.chVol=volrange(ch.chVol+((ch.chVolSlideVal&0xF0)?(ch.chVolSlideVal>>4):-(ch.chVolSlideVal&0xF)));
  838.       break;
  839.     case 17:
  840.       if (tick0)
  841.         break;
  842.       if (ch.chGVolSlideVal&0xF0)
  843.         globalvol=volrange(globalvol+(ch.chGVolSlideVal>>4));
  844.       else
  845.         globalvol=volrange(globalvol-(ch.chGVolSlideVal&0xF));
  846.       break;
  847.     case 20:
  848.       if (tick0)
  849.         break;
  850.       if (curtick==ch.chActionTick)
  851.       {
  852.         ch.chSustain=0;
  853.         if (ch.cursamp&&(ch.cursamp->volenv>=nenv))
  854.           ch.chFadeVol=0;
  855.       }
  856.       break;
  857.     case 25:
  858.       if (tick0)
  859.         break;
  860.       ch.chFinalPan=ch.chPan=panrange(ch.chPan+((ch.chPanSlideVal&0xF0)?(ch.chPanSlideVal>>4):-(ch.chPanSlideVal&0xF)));
  861.       break;
  862.     case 27:
  863.       if (ch.chMRetrigPos++!=ch.chMRetrigLen)
  864.         break;
  865.       ch.chMRetrigPos=0;
  866.       ch.nextpos=0;
  867.  
  868.       switch (ch.chMRetrigAct)
  869.       {
  870.       case 0: case 8: break;
  871.       case 1: case 2: case 3: case 4: case 5:
  872.         ch.chVol=ch.chVol-(1<<(ch.chMRetrigAct-1));
  873.         break;
  874.       case 9: case 10: case 11: case 12: case 13:
  875.         ch.chVol=ch.chVol+(1<<(ch.chMRetrigAct-9));
  876.         break;
  877.       case 6:  ch.chVol=(ch.chVol*5)>>3; break;
  878.       case 14: ch.chVol=(ch.chVol*3)>>1; break;
  879.       case 7:  ch.chVol>>=1; break;
  880.       case 15: ch.chVol<<=1; break;
  881.       }
  882.       ch.chFinalVol=ch.chVol=volrange(ch.chVol);
  883.       break;
  884.     case 29:
  885.       if (ch.chTremorPos>=ch.chTremorOff)
  886.         ch.chFinalVol=0;
  887.       if (tick0)
  888.         break;
  889.       ch.chTremorPos++;
  890.       if (ch.chTremorPos==ch.chTremorLen)
  891.         ch.chTremorPos=0;
  892.       break;
  893.     case 45:
  894.       if (!ch.chActionTick)
  895.         break;
  896.       if (!(curtick%ch.chActionTick))
  897.         ch.nextpos=0;
  898.       break;
  899.     case 48:
  900.       if (tick0)
  901.         break;
  902.       if (curtick==ch.chActionTick)
  903.         ch.chFinalVol=ch.chVol=0;
  904.       break;
  905.     case 49:
  906.       if (tick0)
  907.         break;
  908.       if (curtick!=ch.chActionTick)
  909.         break;
  910.       notedelayed=1;
  911.       procnot=ch.chDelayNote;
  912.       procins=ch.chCurIns;
  913.       proccmd=0;
  914.       procdat=0;
  915.       procvol=0;
  916.       PlayNote(ch);
  917.       break;
  918.     }
  919.  
  920.     if (!ch.cursamp)
  921.     {
  922.       mcpSet(i, mcpCStatus, 0);
  923.       continue;
  924.     }
  925.     sample &sm=*ch.cursamp;
  926.  
  927.     int vol=(ch.chFinalVol*globalvol)>>4;
  928.     int pan=ch.chFinalPan-128;
  929.     if (!ch.chSustain)
  930.     {
  931.       vol=(vol*ch.chFadeVol)>>15;
  932.       if (ch.chFadeVol>=sm.volfade)
  933.         ch.chFadeVol-=sm.volfade;
  934.       else
  935.         ch.chFadeVol=0;
  936.     }
  937.  
  938.     if (sm.volenv<nenv)
  939.     {
  940.       const envelope &env=envelopes[sm.volenv];
  941.       vol=(env.env[ch.chVolEnvPos]*vol)>>8;
  942.  
  943.       if (ch.chVolEnvPos<env.len)
  944.         ch.chVolEnvPos++;
  945.       if (ch.chSustain&&(env.type&mpEnvSLoop))
  946.       {
  947.         if (ch.chVolEnvPos==env.sloope)
  948.           ch.chVolEnvPos=env.sloops;
  949.       }
  950.       else
  951.         if (env.type&mpEnvLoop)
  952.         {
  953.           if (ch.chVolEnvPos==env.loope)
  954.             ch.chVolEnvPos=env.loops;
  955.         }
  956.     }
  957.  
  958.     if (sm.panenv<nenv)
  959.     {
  960.       const envelope &env=envelopes[sm.panenv];
  961.       pan+=((env.env[ch.chPanEnvPos]-128)*(128-((pan<0)?-pan:pan)))>>7;
  962.  
  963.       if (ch.chPanEnvPos<env.len)
  964.         ch.chPanEnvPos++;
  965.       if (ch.chSustain&&(env.type&mpEnvSLoop))
  966.       {
  967.         if (ch.chPanEnvPos==env.sloope)
  968.           ch.chPanEnvPos=env.sloops;
  969.       }
  970.       else
  971.       if (env.type&mpEnvLoop)
  972.       {
  973.         if (ch.chPanEnvPos==env.loope)
  974.           ch.chPanEnvPos=env.loops;
  975.       }
  976.     }
  977.  
  978.     if (sm.vibrate&&sm.vibdepth)
  979.     {
  980.       int dep=0;
  981.       switch (sm.vibtype)
  982.       {
  983.       case 0:
  984.         dep=(sintab[(ch.chAVibPos>>8)&0xFF]*sm.vibdepth)>>11;
  985.         break;
  986.       case 1:
  987.         dep=(ch.chAVibPos&0x8000)?-sm.vibdepth:sm.vibdepth;
  988.         break;
  989.       case 2:
  990.         dep=(sm.vibdepth*(32768-ch.chAVibPos))>>14;
  991.         break;
  992.       case 3:
  993.         dep=(sm.vibdepth*(ch.chAVibPos-32768))>>14;
  994.         break;
  995.       }
  996.  
  997.       ch.chAVibSwpPos+=sm.vibsweep;
  998.       if (ch.chAVibSwpPos>0x10000)
  999.         ch.chAVibSwpPos=0x10000;
  1000.       dep=(dep*(int)ch.chAVibSwpPos)>>16;
  1001.  
  1002.       ch.chFinalPitch-=dep;
  1003.  
  1004.       ch.chAVibPos+=sm.vibrate;
  1005.     }
  1006.  
  1007.     if (ch.nextstop)
  1008.       mcpSet(i, mcpCStatus, 0);
  1009.     if (ch.nextsamp!=-1)
  1010.       mcpSet(i, mcpCInstrument, ch.nextsamp);
  1011.     if (ch.nextpos!=-1)
  1012.     {
  1013.       mcpSet(i, mcpCPosition, ch.nextpos);
  1014.       mcpSet(i, mcpCStatus, 1);
  1015.     }
  1016.     if (linearfreq)
  1017.       mcpSet(i, mcpCPitch, -ch.chFinalPitch);
  1018.     else
  1019.       mcpSet(i, mcpCPitch6848, ch.chFinalPitch);
  1020.     mcpSet(i, mcpCVolume, (looping||!looped)?vol:0);
  1021.     mcpSet(i, mcpCPanning, pan);
  1022.     mcpSet(i, mcpCMute, mutech[i]);
  1023.   }
  1024. }
  1025.  
  1026.  
  1027.  
  1028. int xmpChanActive(int ch)
  1029. {
  1030.   return mcpGet(ch, mcpCStatus)&&channels[ch].cursamp&&channels[ch].chVol&&channels[ch].chFadeVol;
  1031. }
  1032.  
  1033. int xmpGetChanIns(int ch)
  1034. {
  1035.   return channels[ch].chCurIns;
  1036. }
  1037.  
  1038. int xmpGetChanSamp(int ch)
  1039. {
  1040.   if (!channels[ch].cursamp)
  1041.     return 0xFFFF;
  1042.   return channels[ch].cursamp-samples;
  1043. }
  1044.  
  1045. int xmpGetDotsData(int ch, int &smp, int &frq, int &voll, int &volr, int &sus)
  1046. {
  1047.   if (!mcpGet(ch, mcpCStatus))
  1048.     return 0;
  1049.   channel &c=channels[ch];
  1050.   if (!c.cursamp||!c.chVol||!c.chFadeVol)
  1051.     return 0;
  1052.   smp=c.cursamp-samples;
  1053.   if (linearfreq)
  1054.     frq=60*256+c.cursamp->normnote-freqrange(c.chFinalPitch);
  1055.   else
  1056.     frq=60*256+c.cursamp->normnote+mcpGetNote8363(6848*8363/freqrange(c.chFinalPitch));
  1057.   mcpGetRealVolume(ch, voll, volr);
  1058.   sus=c.chSustain;
  1059.   return 1;
  1060. }
  1061.  
  1062. void xmpGetRealVolume(int ch, int &voll, int &volr)
  1063. {
  1064.   mcpGetRealVolume(ch, voll, volr);
  1065. }
  1066.  
  1067. unsigned short xmpGetPos()
  1068. {
  1069.   return (curord<<8)|currow;
  1070. }
  1071.  
  1072. void xmpSetPos(int ord, int row)
  1073. {
  1074.   if (row<0)
  1075.     ord--;
  1076.   if (ord>=nord)
  1077.     ord=0;
  1078.   if (ord<0)
  1079.   {
  1080.     ord=0;
  1081.     row=0;
  1082.   }
  1083.   if (row>=patlens[orders[ord]])
  1084.   {
  1085.     ord++;
  1086.     row=0;
  1087.   }
  1088.   if (ord>=nord)
  1089.     ord=0;
  1090.   if (row<0)
  1091.   {
  1092.     row+=patlens[orders[ord]];
  1093.     if (row<0)
  1094.       row=0;
  1095.   }
  1096.   int i;
  1097.   for (i=0; i<nchan; i++)
  1098.     mcpSet(i, mcpCReset, 0);
  1099.   jumptoord=ord;
  1100.   jumptorow=row;
  1101.   curtick=curtempo;
  1102.   curord=ord;
  1103.   currow=row;
  1104.   usersetpos=1;
  1105. }
  1106.  
  1107. int xmpGetLChanSample(int ch, short *b, int len, int rate)
  1108. {
  1109.   return mcpGetChanSample(ch, b, len, rate);
  1110. }
  1111.  
  1112. void xmpMute(int i, int m)
  1113. {
  1114.   mutech[i]=m;
  1115. }
  1116.  
  1117. int xmpLoop()
  1118. {
  1119.   return looped;
  1120. }
  1121.  
  1122. void xmpSetLoop(int x)
  1123. {
  1124.   looping=x;
  1125. }
  1126.  
  1127. int xmpPlayModule(xmodule &m)
  1128. {
  1129.   int i;
  1130.   mcpLoadSamples(m.sampleinfos, m.nsampi);
  1131.  
  1132.   memset(channels, 0, sizeof(channels));
  1133.  
  1134.   globalvol=0x40;
  1135.   jumptorow=0;
  1136.   jumptoord=0;
  1137.   curord=0;
  1138.   currow=0;
  1139.   ninst=m.ninst;
  1140.   nord=m.nord;
  1141.   nsamp=m.nsamp;
  1142.   instruments=m.instruments;
  1143.   envelopes=m.envelopes;
  1144.   samples=m.samples;
  1145.   patterns=m.patterns;
  1146.   orders=m.orders;
  1147.   patlens=m.patlens;
  1148.   linearfreq=m.linearfreq;
  1149.   nchan=m.nchan;
  1150.   loopord=m.loopord;
  1151.   nenv=m.nenv;
  1152.   looped=0;
  1153.  
  1154.   curtempo=m.initempo;
  1155.   curtick=m.initempo-1;
  1156.  
  1157.   for (i=0; i<nchan; i++)
  1158.   {
  1159.     channels[i].chPan=((i*3)&2)?0xFF:0x00;
  1160.     mutech[i]=0;
  1161.   }
  1162.  
  1163.   firstspeed=256*2*m.inibpm/5;
  1164.   if (!mcpOpenPlayer(nchan, xmpPlayTick))
  1165.     return 0;
  1166.  
  1167.   if (nchan!=mcpNChan)
  1168.   {
  1169.     mcpClosePlayer();
  1170.     return 0;
  1171.   }
  1172.  
  1173.   return 1;
  1174. }
  1175.  
  1176. void xmpStopModule()
  1177. {
  1178.   mcpClosePlayer();
  1179. }
  1180.  
  1181. int xmpLoadModule(xmodule &m, binfile &file)
  1182. {
  1183.   m.envelopes=0;
  1184.   m.samples=0;
  1185.   m.instruments=0;
  1186.   m.sampleinfos=0;
  1187.   m.patlens=0;
  1188.   m.patterns=0;
  1189.   m.orders=0;
  1190.  
  1191.   struct
  1192.   {
  1193.     char sig[17];
  1194.     char name[20];
  1195.     char eof;
  1196.     char tracker[20];
  1197.     unsigned short ver;
  1198.     unsigned long hdrsize;
  1199.   } head1;
  1200.  
  1201.   struct
  1202.   {
  1203.     unsigned short nord;
  1204.     unsigned short loopord;
  1205.     unsigned short nchan;
  1206.     unsigned short npat;
  1207.     unsigned short ninst;
  1208.     unsigned short freqtab;
  1209.     unsigned short tempo;
  1210.     unsigned short bpm;
  1211.     unsigned char ord[256];
  1212.   } head2;
  1213.  
  1214.   file.read(&head1, sizeof(head1));
  1215.   if (memcmp(head1.sig, "Extended Module: ", 17))
  1216.     return errFormStruc;
  1217.   if (head1.eof!=26)
  1218.     return errFormStruc;
  1219.   if (head1.ver<0x104)
  1220.     return errFormOldVer;
  1221.   file.read(&head2, sizeof(head2));
  1222.   file.seekcur(head1.hdrsize-4-sizeof(head2));
  1223.  
  1224.   if (!head2.ninst)
  1225.     return errFormMiss;
  1226.  
  1227.   memcpy(m.name, head1.name, 20);
  1228.   m.name[20]=0;
  1229.  
  1230.   m.linearfreq=!!(head2.freqtab&1);
  1231.   m.nchan=head2.nchan;
  1232.   m.ninst=head2.ninst;
  1233.   m.nenv=head2.ninst*2;
  1234.   m.npat=head2.npat+1;
  1235.   m.nord=head2.nord;
  1236.   m.loopord=head2.loopord;
  1237.   m.inibpm=head2.bpm;
  1238.   m.initempo=head2.tempo;
  1239.  
  1240.   m.orders=new unsigned short [head2.nord];
  1241.   m.patterns=(unsigned char (**)[5])new void *[head2.npat+1];
  1242.   m.patlens=new unsigned short [head2.npat+1];
  1243.   m.instruments=new instrument [head2.ninst];
  1244.   m.envelopes=new envelope [head2.ninst*2];
  1245.   sampleinfo **smps=new sampleinfo *[head2.ninst];
  1246.   sample **msmps=new sample *[head2.ninst];
  1247.   int *instsmpnum=new int [head2.ninst];
  1248.  
  1249.   if (!smps||!msmps||!instsmpnum||!m.instruments||!m.envelopes||!m.patterns||!m.orders||!m.patlens)
  1250.     return errAllocMem;
  1251.  
  1252.   memset(m.patterns, 0, (head2.npat+1)*sizeof(void*));
  1253.   memset(m.envelopes, 0, (head2.ninst*2)*sizeof(envelope));
  1254.  
  1255.   int i,j,k;
  1256.  
  1257.   for (i=0; i<head2.nord; i++)
  1258.     m.orders[i]=(head2.ord[i]<head2.npat)?head2.ord[i]:head2.npat;
  1259.  
  1260.   m.patlens[head2.npat]=64;
  1261.   m.patterns[head2.npat]=new unsigned char [64*head2.nchan][5];
  1262.   if (!m.patterns[head2.npat])
  1263.     return errAllocMem;
  1264.   memset(m.patterns[head2.npat], 0, 64*5*head2.nchan);
  1265.  
  1266.   for (i=0; i<head2.npat; i++)
  1267.   {
  1268.     struct
  1269.     {
  1270.       unsigned long len;
  1271.       unsigned char ptype;
  1272.       unsigned short rows;
  1273.       unsigned short patdata;
  1274.     } pathead;
  1275.     file.read(&pathead, sizeof(pathead));
  1276.     file.seekcur(pathead.len-sizeof(pathead));
  1277.     m.patlens[i]=pathead.rows;
  1278.     m.patterns[i]=new unsigned char [pathead.rows*head2.nchan][5];
  1279.     if (!m.patterns[i])
  1280.       return errAllocMem;
  1281.     memset(m.patterns[i], 0, pathead.rows*head2.nchan*5);
  1282.     if (!pathead.patdata)
  1283.       continue;
  1284.     unsigned char *pbuf=new unsigned char [pathead.patdata];
  1285.     if (!pbuf)
  1286.       return errAllocMem;
  1287.     file.read(pbuf, pathead.patdata);
  1288.     unsigned char *pbp=pbuf;
  1289.     unsigned char *cur=(unsigned char*)(m.patterns[i]);
  1290.     for (j=0; j<(pathead.rows*head2.nchan); j++)
  1291.     {
  1292.       unsigned char pack=(*pbp&0x80)?(*pbp++):0x1F;
  1293.       for (k=0; k<5; k++)
  1294.       {
  1295.         *cur++=(pack&1)?*pbp++:0;
  1296.         pack>>=1;
  1297.       }
  1298.       if (cur[-2]==0xE)
  1299.       {
  1300.         cur[-2]=36+(cur[-1]>>4);
  1301.         cur[-1]&=0xF;
  1302.       }
  1303.     }
  1304.     delete pbuf;
  1305.   }
  1306.  
  1307.   m.nsampi=0;
  1308.   m.nsamp=0;
  1309.   for (i=0; i<m.ninst; i++)
  1310.   {
  1311.     instrument &ip=m.instruments[i];
  1312.     envelope *env=m.envelopes+2*i;
  1313.     smps[i]=0;
  1314.     msmps[i]=0;
  1315.     struct
  1316.     {
  1317.       unsigned long size;
  1318.       char name[22];
  1319.       char type;
  1320.       unsigned short samp;
  1321.     } ins1;
  1322.     file.read(&ins1, sizeof(ins1));
  1323.     memcpy(ip.name, ins1.name, 22);
  1324.     ip.name[22]=0;
  1325.     memset(ip.samples, -1, 256);
  1326.     instsmpnum[i]=ins1.samp;
  1327.     if (!ins1.samp)
  1328.     {
  1329.       file.seekcur(ins1.size-sizeof(ins1));
  1330.       continue;
  1331.     }
  1332.     struct
  1333.     {
  1334.       unsigned long shsize;
  1335.       unsigned char snum[96];
  1336.       unsigned short venv[12][2];
  1337.       unsigned short penv[12][2];
  1338.       unsigned char vnum, pnum;
  1339.       unsigned char vsustain, vloops, vloope, psustain, ploops, ploope;
  1340.       unsigned char vtype, ptype;
  1341.       unsigned char vibtype, vibsweep, vibdepth, vibrate;
  1342.       unsigned short volfade;
  1343.       unsigned short res;
  1344.     } ins2;
  1345.     file.read(&ins2, sizeof(ins2));
  1346.     file.seekcur(ins1.size-sizeof(ins1)-sizeof(ins2));
  1347.  
  1348.     smps[i]=new sampleinfo[ins1.samp];
  1349.     msmps[i]=new sample[ins1.samp];
  1350.     if (!smps[i]||!msmps[i])
  1351.       return errAllocMem;
  1352.     memset(msmps[i], 0, sizeof(**msmps)*ins1.samp);
  1353.     memset(smps[i], 0, sizeof(**smps)*ins1.samp);
  1354.  
  1355.     memset(ip.samples, 0xFF, 128*2);
  1356.     for (j=0; j<96; j++)
  1357.       if (ins2.snum[j]<ins1.samp)
  1358.         ip.samples[j]=m.nsamp+ins2.snum[j];
  1359.     unsigned short volfade=0xFFFF;
  1360.     volfade=ins2.volfade;
  1361.     if (ins2.vtype&1)
  1362.     {
  1363.       env[0].speed=0;
  1364.       env[0].type=0;
  1365.       env[0].env=new unsigned char[ins2.venv[ins2.vnum-1][0]+1];
  1366.       if (!env[0].env)
  1367.         return errAllocMem;
  1368.       short k, p=0, h=ins2.venv[0][1]*4;
  1369.       for (j=1; j<ins2.vnum; j++)
  1370.       {
  1371.         short l=ins2.venv[j][0]-p;
  1372.         short dh=ins2.venv[j][1]*4-h;
  1373.         for (k=0; k<l; k++)
  1374.         {
  1375.           short cv=h+dh*k/l;
  1376.           env[0].env[p++]=(cv>255)?255:cv;
  1377.         }
  1378.         h+=dh;
  1379.       }
  1380.       env[0].len=p;
  1381.       env[0].env[p]=(h>255)?255:h;
  1382.       if (ins2.vtype&2)
  1383.       {
  1384.         env[0].type|=mpEnvSLoop;
  1385.         if (!(ins2.vtype&4)||(ins2.vsustain<=ins2.vloope))
  1386.         {
  1387.           env[0].sloops=ins2.venv[ins2.vsustain][0];
  1388.           env[0].sloope=ins2.venv[ins2.vsustain][0]+1;
  1389.         }
  1390.         else
  1391.         {
  1392.           env[0].sloops=ins2.venv[ins2.vloops][0];
  1393.           env[0].sloope=ins2.venv[ins2.vloope][0];
  1394.         }
  1395.       }
  1396.       if (ins2.vtype&4)
  1397.       {
  1398.         if ((ins2.vtype&2)&&(ins2.vsustain==ins2.vloope))
  1399.         {
  1400.           env[0].type|=mpEnvSLoop;
  1401.           env[0].sloops=ins2.venv[ins2.vloops][0];
  1402.           env[0].sloope=ins2.venv[ins2.vloope][0];
  1403.         }
  1404.         else
  1405.         {
  1406.           env[0].type|=mpEnvLoop;
  1407.           env[0].loops=ins2.venv[ins2.vloops][0];
  1408.           env[0].loope=ins2.venv[ins2.vloope][0];
  1409.         }
  1410.       }
  1411.     }
  1412.     if (ins2.ptype&1)
  1413.     {
  1414.       env[1].speed=0;
  1415.       env[1].type=0;
  1416.       env[1].env=new unsigned char[ins2.penv[ins2.pnum-1][0]+1];
  1417.       if (!env[1].env)
  1418.         return errAllocMem;
  1419.       short k, p=0, h=ins2.penv[0][1]*4;
  1420.       for (j=1; j<ins2.pnum; j++)
  1421.       {
  1422.         short l=ins2.penv[j][0]-p;
  1423.         short dh=ins2.penv[j][1]*4-h;
  1424.         for (k=0; k<l; k++)
  1425.         {
  1426.           short cv=h+dh*k/l;
  1427.           env[1].env[p++]=(cv>255)?255:cv;
  1428.         }
  1429.         h+=dh;
  1430.       }
  1431.       env[1].len=p;
  1432.       env[1].env[p]=(h>255)?255:h;
  1433.       if (ins2.ptype&2)
  1434.       {
  1435.         env[1].type|=mpEnvSLoop;
  1436.         if (!(ins2.ptype&4)||(ins2.psustain<=ins2.ploope))
  1437.         {
  1438.           env[1].sloops=ins2.penv[ins2.psustain][0];
  1439.           env[1].sloope=ins2.penv[ins2.psustain][0]+1;
  1440.         }
  1441.         else
  1442.         {
  1443.           env[1].sloops=ins2.penv[ins2.ploops][0];
  1444.           env[1].sloope=ins2.penv[ins2.ploope][0];
  1445.         }
  1446.       }
  1447.       if (ins2.ptype&4)
  1448.       {
  1449.         if ((ins2.ptype&2)&&(ins2.psustain==ins2.ploope))
  1450.         {
  1451.           env[1].type|=mpEnvSLoop;
  1452.           env[1].sloops=ins2.penv[ins2.ploops][0];
  1453.           env[1].sloope=ins2.penv[ins2.ploope][0];
  1454.         }
  1455.         else
  1456.         {
  1457.           env[1].type|=mpEnvLoop;
  1458.           env[1].loops=ins2.penv[ins2.ploops][0];
  1459.           env[1].loope=ins2.penv[ins2.ploope][0];
  1460.         }
  1461.       }
  1462.     }
  1463.     for (j=0; j<ins1.samp; j++)
  1464.     {
  1465.       struct
  1466.       {
  1467.         unsigned long samplen;
  1468.         unsigned long loopstart;
  1469.         unsigned long looplen;
  1470.         unsigned char vol;
  1471.         signed char finetune;
  1472.         unsigned char type;
  1473.         unsigned char pan;
  1474.         signed char relnote;
  1475.         unsigned char res;
  1476.         unsigned char name[22];
  1477.       } samp;
  1478.       file.read(&samp, sizeof (samp));
  1479.       file.seekcur(ins2.shsize-sizeof(samp));
  1480.       if (samp.type&16)
  1481.       {
  1482.         samp.samplen>>=1;
  1483.         samp.loopstart>>=1;
  1484.         samp.looplen>>=1;
  1485.       }
  1486.  
  1487.       sample &sp=msmps[i][j];
  1488.       memcpy(sp.name, samp.name, 22);
  1489.       sp.name[22]=0;
  1490.       sp.handle=0xFFFF;
  1491.       sp.normnote=-samp.relnote*256-samp.finetune*2;
  1492.       sp.stdvol=(samp.vol>0x3F)?0xFF:(samp.vol<<2);
  1493.       sp.stdpan=samp.pan;
  1494.       sp.opt=0;
  1495.       sp.volfade=volfade;
  1496.       sp.vibtype=ins2.vibtype;
  1497.       sp.vibdepth=ins2.vibdepth<<2;
  1498.       sp.vibspeed=0;
  1499.       sp.vibrate=ins2.vibrate<<8;
  1500.       sp.vibsweep=0xFFFF/(ins2.vibsweep+1);
  1501.       sp.volenv=env[0].env?(2*i+0):0xFFFF;
  1502.       sp.panenv=env[1].env?(2*i+1):0xFFFF;
  1503.       sp.pchenv=0xFFFF;
  1504.  
  1505.       sampleinfo &sip=smps[i][j];
  1506.       sip.length=samp.samplen;
  1507.       sip.loopstart=samp.loopstart;
  1508.       sip.loopend=samp.loopstart+samp.looplen;
  1509.       sip.samprate=8363;
  1510.       sip.type=mcpSampDelta|((samp.type&16)?mcpSamp16Bit:0)|((samp.type&3)?(((samp.type&3)==2)?(mcpSampLoop|mcpSampBiDi):mcpSampLoop):0);
  1511.     }
  1512.     for (j=0; j<ins1.samp; j++)
  1513.     {
  1514.       sample &sp=msmps[i][j];
  1515.       sampleinfo &sip=smps[i][j];
  1516.       unsigned long l=sip.length<<(!!(sip.type&mcpSamp16Bit));
  1517.       if (!l)
  1518.         continue;
  1519.       sip.ptr=new char [l+16];
  1520.       if (!sip.ptr)
  1521.         return errAllocMem;
  1522.       file.read(sip.ptr, l);
  1523.       sp.handle=m.nsampi++;
  1524.     }
  1525.     m.nsamp+=ins1.samp;
  1526.   }
  1527.  
  1528.   m.samples=new sample [m.nsamp];
  1529.   m.sampleinfos=new sampleinfo [m.nsampi];
  1530.   if (!m.samples||!m.sampleinfos)
  1531.     return errAllocMem;
  1532.  
  1533.   m.nsampi=0;
  1534.   m.nsamp=0;
  1535.   for (i=0; i<m.ninst; i++)
  1536.   {
  1537.     for (j=0; j<instsmpnum[i]; j++)
  1538.     {
  1539.       m.samples[m.nsamp++]=msmps[i][j];
  1540.       if (smps[i][j].ptr)
  1541.         m.sampleinfos[m.nsampi++]=smps[i][j];
  1542.     }
  1543.     delete smps[i];
  1544.     delete msmps[i];
  1545.   }
  1546.   delete smps;
  1547.   delete msmps;
  1548.   delete instsmpnum;
  1549.  
  1550.   return errOk;
  1551. }
  1552.  
  1553. void xmpFreeModule(xmodule &m)
  1554. {
  1555.   int i;
  1556.   if (m.sampleinfos)
  1557.     for (i=0; i<m.nsampi; i++)
  1558.       delete m.sampleinfos[i].ptr;
  1559.   delete m.sampleinfos;
  1560.   delete m.samples;
  1561.   if (m.envelopes)
  1562.     for (i=0; i<m.nenv; i++)
  1563.       delete m.envelopes[i].env;
  1564.   delete m.envelopes;
  1565.   delete m.instruments;
  1566.   if (m.patterns)
  1567.     for (i=0; i<m.npat; i++)
  1568.       delete m.patterns[i];
  1569.   delete m.patterns;
  1570.   delete m.patlens;
  1571.   delete m.orders;
  1572. }
  1573.  
  1574.  
  1575.  
  1576. static unsigned short modnotetab[85]=
  1577. {
  1578.   0xCFF, 0xC44, 0xB94, 0xAED, 0xA50, 0x9BC, 0x930, 0x8AC, 0x830, 0x7BA, 0x74B, 0x6E2,
  1579.   0x67F, 0x622, 0x5CA, 0x577, 0x528, 0x4DE, 0x498, 0x456, 0x418, 0x3DD, 0x3A5, 0x371,
  1580.   0x340, 0x311, 0x2E5, 0x2BB, 0x294, 0x26F, 0x24C, 0x22B, 0x20C, 0x1EE, 0x1D3, 0x1B9,
  1581.   0x1A0, 0x188, 0x172, 0x15E, 0x14A, 0x138, 0x126, 0x116, 0x106, 0x0F7, 0x0E9, 0x0DC,
  1582.   0x0D0, 0x0C4, 0x0B9, 0x0AF, 0x0A5, 0x09C, 0x093, 0x08B, 0x083, 0x07C, 0x075, 0x06E,
  1583.   0x068, 0x062, 0x05D, 0x057, 0x053, 0x04E, 0x04A, 0x045, 0x041, 0x03E, 0x03A, 0x037,
  1584.   0x034, 0x031, 0x02E, 0x02C, 0x029, 0x027, 0x025, 0x023, 0x021, 0x01F, 0x01D, 0x01C, 0
  1585. };
  1586.  
  1587. static inline unsigned long swapb2(unsigned short a)
  1588. {
  1589.   return ((a&0xFF)<<9)|((a&0xFF00)>>7);
  1590. }
  1591.  
  1592. static int loadmod(xmodule &m, binfile &file, int chan, int sig)
  1593. {
  1594.   m.envelopes=0;
  1595.   m.samples=0;
  1596.   m.instruments=0;
  1597.   m.sampleinfos=0;
  1598.   m.patlens=0;
  1599.   m.patterns=0;
  1600.   m.orders=0;
  1601.   m.nenv=0;
  1602.   m.linearfreq=0;
  1603.  
  1604.   unsigned long l=file[1080].getl();
  1605.  
  1606.   m.ninst=31;
  1607.   m.nchan=0;
  1608.  
  1609.   switch (l)
  1610.   {
  1611.   case 0x2E4B2E4D: // M.K.
  1612.   case 0x214B214D: // M!K!
  1613.   case 0x34544C46: // FLT4
  1614.     m.nchan=4;
  1615.     break;
  1616.   case 0x2E542E4E: // N.T.
  1617.     m.nchan=4;
  1618.     m.ninst=15;
  1619.     break;
  1620.   case 0x31384443: m.nchan=8; break; // CD81
  1621.  
  1622.   case 0x315A4454: m.nchan=1; break; // TDZ1
  1623.   case 0x325A4454: m.nchan=2; break;
  1624.   case 0x335A4454: m.nchan=3; break;
  1625.   case 0x345A4454: m.nchan=4; break;
  1626.   case 0x355A4454: m.nchan=5; break;
  1627.   case 0x365A4454: m.nchan=6; break;
  1628.   case 0x375A4454: m.nchan=7; break;
  1629.   case 0x385A4454: m.nchan=8; break;
  1630.   case 0x395A4454: m.nchan=9; break;
  1631.  
  1632.   case 0x4E484331: m.nchan=1; break; // 1CHN...
  1633.   case 0x4E484332: m.nchan=2; break;
  1634.   case 0x4E484333: m.nchan=3; break;
  1635.   case 0x4E484334: m.nchan=4; break;
  1636.   case 0x4E484335: m.nchan=5; break;
  1637.   case 0x4E484336: m.nchan=6; break;
  1638.   case 0x4E484337: m.nchan=7; break;
  1639.   case 0x4E484338: m.nchan=8; break;
  1640.   case 0x4E484339: m.nchan=9; break;
  1641.   case 0x48433031: m.nchan=10; break; // 10CH...
  1642.   case 0x48433131: m.nchan=11; break;
  1643.   case 0x48433231: m.nchan=12; break;
  1644.   case 0x48433331: m.nchan=13; break;
  1645.   case 0x48433431: m.nchan=14; break;
  1646.   case 0x48433531: m.nchan=15; break;
  1647.   case 0x48433631: m.nchan=16; break;
  1648.   case 0x48433731: m.nchan=17; break;
  1649.   case 0x48433831: m.nchan=18; break;
  1650.   case 0x48433931: m.nchan=19; break;
  1651.   case 0x48433032: m.nchan=20; break;
  1652.   case 0x48433132: m.nchan=21; break;
  1653.   case 0x48433232: m.nchan=22; break;
  1654.   case 0x48433332: m.nchan=23; break;
  1655.   case 0x48433432: m.nchan=24; break;
  1656.   case 0x48433532: m.nchan=25; break;
  1657.   case 0x48433632: m.nchan=26; break;
  1658.   case 0x48433732: m.nchan=27; break;
  1659.   case 0x48433832: m.nchan=28; break;
  1660.   case 0x48433932: m.nchan=29; break;
  1661.   case 0x48433033: m.nchan=30; break;
  1662.   case 0x48433133: m.nchan=31; break;
  1663.   case 0x48433233: m.nchan=32; break;
  1664.   case 0x38544C46: // FLT8
  1665.     return errFormSupp;
  1666.     m.nchan=8;
  1667.     break;
  1668.   default:
  1669.     if (sig==1)
  1670.       return errFormSig;
  1671.     m.ninst=(sig==2)?31:15;
  1672.     break;
  1673.   }
  1674.  
  1675.   if (chan)
  1676.     m.nchan=chan;
  1677.  
  1678.   if (!m.nchan)
  1679.     return errFormSig;
  1680.  
  1681.   m.nsampi=m.ninst;
  1682.   m.nsamp=m.ninst;
  1683.   m.instruments=new instrument[m.ninst];
  1684.   m.samples=new sample[m.ninst];
  1685.   m.sampleinfos=new sampleinfo[m.ninst];
  1686.   if (!m.instruments||!m.samples||!m.sampleinfos)
  1687.     return errAllocMem;
  1688.   memset(m.samples, 0, sizeof(*m.samples)*m.ninst);
  1689.   memset(m.sampleinfos, 0, sizeof(*m.sampleinfos)*m.ninst);
  1690.  
  1691.   file[0].read(m.name, 20);
  1692.   m.name[20]=0;
  1693.  
  1694.   int i;
  1695.  
  1696.   for (i=0; i<m.ninst; i++)
  1697.   {
  1698.     struct
  1699.     {
  1700.       char name[22];
  1701.       unsigned short length;
  1702.       signed char finetune;
  1703.       unsigned char volume;
  1704.       unsigned short loopstart;
  1705.       unsigned short looplength;
  1706.     } mi;
  1707.     file.read(&mi, sizeof(mi));
  1708.     unsigned long length=swapb2(mi.length);
  1709.     unsigned long loopstart=swapb2(mi.loopstart);
  1710.     unsigned long looplength=swapb2(mi.looplength);
  1711.     if (length<4)
  1712.       length=0;
  1713.     if (looplength<4)
  1714.       looplength=0;
  1715.     if (!looplength||(loopstart>=length))
  1716.       looplength=0;
  1717.     else
  1718.       if ((loopstart+looplength)>length)
  1719.         looplength=length-loopstart;
  1720.     if (mi.finetune&0x08)
  1721.       mi.finetune|=0xF0;
  1722.  
  1723.     instrument &ip=m.instruments[i];
  1724.     sample &sp=m.samples[i];
  1725.     sampleinfo &sip=m.sampleinfos[i];
  1726.  
  1727.     memcpy(ip.name, mi.name, 22);
  1728.     int j;
  1729.     for (j=21; j>=0; j--)
  1730.       if (ip.name[j]>=0x20)
  1731.         break;
  1732.     ip.name[j+1]=0;
  1733.     memset(ip.samples, -1, 256);
  1734.     *sp.name=0;
  1735.     sp.handle=0xFFFF;
  1736.     sp.stdpan=-1;
  1737.     sp.opt=0;
  1738.     sp.normnote=-mi.finetune*32;
  1739.     sp.stdvol=(mi.volume>0x3F)?0xFF:(mi.volume<<2);
  1740.     sp.volenv=0xFFFF;
  1741.     sp.panenv=0xFFFF;
  1742.     sp.pchenv=0xFFFF;
  1743.     sp.volfade=0;
  1744.     sp.vibspeed=0;
  1745.     sp.vibrate=0;
  1746.     if (!length)
  1747.       continue;
  1748.     for (j=0; j<128; j++)
  1749.       ip.samples[j]=i;
  1750.     sp.handle=i;
  1751.  
  1752.     sip.length=length;
  1753.     sip.loopstart=loopstart;
  1754.     sip.loopend=loopstart+looplength;
  1755.     sip.samprate=8363;
  1756.     sip.type=looplength?mcpSampLoop:0;
  1757.   }
  1758.  
  1759.   unsigned char orders[128];
  1760.   unsigned char ordn=file.getc();
  1761.   unsigned char loopp=file.getc();
  1762.  
  1763.   file.read(orders, 128);
  1764.   if (loopp>=ordn)
  1765.     loopp=0;
  1766.   short pn=0;
  1767.   short t;
  1768.   for (t=0; t<128; t++)
  1769.     if (pn<orders[t])
  1770.       pn=orders[t];
  1771.   pn++;
  1772.  
  1773.   m.nord=ordn;
  1774.   m.loopord=loopp;
  1775.  
  1776.   m.npat=pn;
  1777.  
  1778.   m.initempo=6;
  1779.   m.inibpm=125;
  1780.  
  1781.   if (sig)
  1782.     file.getl();
  1783.  
  1784.   m.orders=new unsigned short [m.nord];
  1785.   m.patlens=new unsigned short [m.npat];
  1786.   m.patterns=(unsigned char (**)[5])new void *[m.npat];
  1787.   unsigned char *temppat=new unsigned char [4*64*m.nchan];
  1788.   if (!m.orders||!m.patlens||!m.patterns||!temppat)
  1789.     return errAllocMem;
  1790.  
  1791.   for (i=0; i<m.nord; i++)
  1792.     m.orders[i]=orders[i];
  1793.  
  1794.   memset(m.patterns, 0, sizeof(*m.patterns)*m.npat);
  1795.  
  1796.   for (i=0; i<m.npat; i++)
  1797.   {
  1798.     m.patlens[i]=64;
  1799.     m.patterns[i]=new unsigned char [64*m.nchan][5];
  1800.     if (!m.patterns[i])
  1801.       return errAllocMem;
  1802.   }
  1803.  
  1804.   for (i=0; i<pn; i++)
  1805.   {
  1806.     unsigned char *dp=(unsigned char *)(m.patterns[i]);
  1807.     unsigned char *sp=temppat;
  1808.     file.read(temppat, 256*m.nchan);
  1809.     int j;
  1810.     for (j=0; j<(64*m.nchan); j++)
  1811.     {
  1812.       unsigned short nvalue=((short)(sp[0]&0xF)<<8)+sp[1];
  1813.       dp[0]=0;
  1814.       if (nvalue)
  1815.       {
  1816.         int k;
  1817.         for (k=0; k<85; k++)
  1818.           if (modnotetab[k]<=nvalue)
  1819.             break;
  1820.         dp[0]=k+13;
  1821.       }
  1822.       dp[1]=(sp[2]>>4)|(sp[0]&0x10);
  1823.       dp[2]=0;
  1824.       dp[3]=sp[2]&0xF;
  1825.       dp[4]=sp[3];
  1826.  
  1827.       if (dp[3]==0xE)
  1828.       {
  1829.         dp[3]=36+(dp[4]>>4);
  1830.         dp[4]&=0xF;
  1831.       }
  1832.       if (!dp[4])
  1833.         switch (dp[3])
  1834.         {
  1835.         case 10: case 46: case 47:
  1836.           dp[3]=0;
  1837.         }
  1838.  
  1839.       sp+=4;
  1840.       dp+=5;
  1841.     }
  1842.   }
  1843.   delete temppat;
  1844.  
  1845.   for (i=0; i<m.ninst; i++)
  1846.   {
  1847.     instrument &ip=m.instruments[i];
  1848.     sample &sp=m.samples[i];
  1849.     sampleinfo &sip=m.sampleinfos[i];
  1850.     if (sp.handle==0xFFFF)
  1851.       continue;
  1852.     sip.ptr=new unsigned char[sip.length+8];
  1853.     if (!sip.ptr)
  1854.       return errAllocMem;
  1855.     memset(sip.ptr, 0, sip.length);
  1856.     file.read(sip.ptr, sip.length);
  1857.     sp.handle=i;
  1858.   }
  1859.  
  1860.   return errOk;
  1861. }
  1862.  
  1863. int xmpLoadMOD(xmodule &m, binfile &file)
  1864. {
  1865.   return loadmod(m, file, 0, 1);
  1866. }
  1867.  
  1868. int xmpLoadM31(xmodule &m, binfile &file)
  1869. {
  1870.   return loadmod(m, file, 4, 2);
  1871. }
  1872.  
  1873. int xmpLoadM15(xmodule &m, binfile &file)
  1874. {
  1875.   return loadmod(m, file, 4, 0);
  1876. }
  1877.  
  1878. int xmpLoadWOW(xmodule &m, binfile &file)
  1879. {
  1880.   return loadmod(m, file, 8, 1);
  1881. }
  1882.